﻿#region using declarations

using System;
using DPSF;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;

#endregion

namespace NGen.Managers.Particles.Examples {
#if (WINDOWS)
	[Serializable]
#endif
	public class ExampleSpriteParticleSystem : DefaultSpriteParticleSystem {
		/// <summary>
		/// 	construct a new particle system.
		/// 	inherited particle system wants a reference to the Game class for optional functionality, we give it null
		/// </summary>
		public ExampleSpriteParticleSystem() : base(null) {}

		public override void AutoInitialize(GraphicsDevice p_graphicsDevice, ContentManager p_contentManager, SpriteBatch p_spriteBatch) {
			// Initialize the Particle System before doing anything else
			InitializeSpriteParticleSystem(p_graphicsDevice, p_contentManager, 1000, 500000, "Content\\Textures\\Baseball");

			// Set the Name of the Particle System
			Name = GetType().Name;

			// Finish loading the Particle System in a separate function call, so if
			// we want to reset the Particle System later we don't need to completely 
			// re-initialize it, we can just call this function to reset it.
			LoadParticleSystem();
		}

		private void LoadParticleSystem() {
			//-----------------------------------------------------------
			// TODO: Setup the Particle System to achieve the desired result.
			// You may change all of the code in this function. It is just
			// provided to show you how to setup a simple particle system.
			//-----------------------------------------------------------

			// Set the Function to use to Initialize new Particles.
			// The Default Templates include a Particle Initialization Function called
			// InitializeParticleUsingInitialProperties, which initializes new Particles
			// according to the settings in the InitialProperties object (see further below).
			// You can also create your own Particle Initialization Functions as well, as shown with
			// the InitializeParticleProperties function below.
			ParticleInitializationFunction = InitializeParticleUsingInitialProperties;
			//ParticleInitializationFunction = InitializeParticleProperties;

			// Setup the Initial Properties of the Particles.
			// These are only applied if using InitializeParticleUsingInitialProperties 
			// as the Particle Initialization Function.
			InitialProperties.LifetimeMin = 5.0f;
			InitialProperties.LifetimeMax = 5.0f;
			InitialProperties.PositionMin = Vector3.Zero;
			InitialProperties.PositionMax = Vector3.Zero;
			InitialProperties.VelocityMin = new Vector3(-50, -100, 0);
			InitialProperties.VelocityMax = new Vector3(50, 100, 0);
			InitialProperties.AccelerationMin = new Vector3(-5, -5, 0);
			InitialProperties.AccelerationMax = new Vector3(5, 5, 0);
			InitialProperties.RotationMin = 0;
			InitialProperties.RotationMax = 0;
			InitialProperties.RotationalVelocityMin = 0;
			InitialProperties.RotationalVelocityMax = 0;
			InitialProperties.StartWidthMin = 10;
			InitialProperties.StartWidthMax = 40;
			InitialProperties.StartHeightMin = 10;
			InitialProperties.StartHeightMax = 40;
			InitialProperties.EndWidthMin = 30;
			InitialProperties.EndWidthMax = 30;
			InitialProperties.EndHeightMin = 30;
			InitialProperties.EndHeightMax = 30;
			InitialProperties.StartColorMin = Color.Black;
			InitialProperties.StartColorMax = Color.White;
			InitialProperties.EndColorMin = Color.Black;
			InitialProperties.EndColorMax = Color.White;

			// Remove all Events first so that none are added twice if this function is called again
			ParticleEvents.RemoveAllEvents();
			ParticleSystemEvents.RemoveAllEvents();

			// Allow the Particle's Position, Rotation, Width and Height, Color, Transparency, and Orientation to be updated each frame
			ParticleEvents.AddEveryTimeEvent(UpdateParticlePositionUsingVelocity);
			ParticleEvents.AddEveryTimeEvent(UpdateParticleRotationUsingRotationalVelocity);
			ParticleEvents.AddEveryTimeEvent(UpdateParticleWidthAndHeightUsingLerp);
			ParticleEvents.AddEveryTimeEvent(UpdateParticleColorUsingLerp);

			// This function must be executed after the Color Lerp function as the Color Lerp will overwrite the Color's
			// Transparency value, so we give this function an Execution Order of 100 to make sure it is executed last.
			ParticleEvents.AddEveryTimeEvent(UpdateParticleTransparencyToFadeOutUsingLerp, 100);

			// Set the Particle System's Emitter to toggle on and off every 0.5 seconds
			ParticleSystemEvents.LifetimeData.EndOfLifeOption = CParticleSystemEvents.EParticleSystemEndOfLifeOptions.Repeat;
			ParticleSystemEvents.LifetimeData.Lifetime = 10.0f;
			ParticleSystemEvents.AddTimedEvent(0.0f, UpdateParticleSystemEmitParticlesAutomaticallyOn);
			ParticleSystemEvents.AddTimedEvent(10.0f, UpdateParticleSystemEmitParticlesAutomaticallyOff);

			// Setup the Emitter
			Emitter.ParticlesPerSecond = 500;
			Emitter.PositionData.Position = new Vector3(GameEngine.GameWindow.ClientBounds.Width / 2f, GameEngine.GameWindow.ClientBounds.Height / 2f, 0);
		}

		/// <summary>
		/// 	Example of how to create a Particle Initialization Function
		/// </summary>
		/// <param name = "p_particle">The Particle to be Initialized</param>
		public void InitializeParticleProperties(DefaultSpriteParticle p_particle) {
			//-----------------------------------------------------------
			// TODO: Initialize all of the Particle's properties here.
			// If you plan on simply using the default InitializeParticleUsingInitialProperties
			// Particle Initialization Function (see the LoadParticleSystem() function above), 
			// then you may delete this function all together.
			//-----------------------------------------------------------

			// Set the Particle's Lifetime (how long it should exist for)
			p_particle.Lifetime = 10.0f;

			// Set the Particle's initial Position to be wherever the Emitter is
			p_particle.Position = Emitter.PositionData.Position;

			// Set the Particle's Velocity
			var sVelocityMin = new Vector3(-50, 50, 0);
			var sVelocityMax = new Vector3(50, 100, 0);
			p_particle.Velocity = DPSFHelper.RandomVectorBetweenTwoVectors(sVelocityMin, sVelocityMax);

			// Adjust the Particle's Velocity direction according to the Emitter's Orientation
			p_particle.Velocity = Vector3.Transform(p_particle.Velocity, Emitter.OrientationData.Orientation);

			// Give the Particle a random Size
			// Since we have Size Lerp enabled we must also set the Start and End Size
			p_particle.Width = p_particle.StartWidth = p_particle.EndWidth = p_particle.Height = p_particle.StartHeight = p_particle.EndHeight = RandomNumber.Next(10, 50);

			// Give the Particle a random Color
			// Since we have Color Lerp enabled we must also set the Start and End Color
			p_particle.Color = p_particle.StartColor = p_particle.EndColor = DPSFHelper.RandomColor();
		}
	}
}